package snowflake

import (
	"sync"

	"github.com/bwmarrin/snowflake"
	"github.com/gogf/gf/frame/g"
	"github.com/gogf/gf/util/gconv"
)

type Node struct {
	node *snowflake.Node
}

const (
	NameDefault = `default` // 默认的id生成器，生成数量一般够用了
)

var (
	nodes       = make(map[string]*Node) // 不同的生成器生成的id有可能重复，主要要在不同的表使用
	nodesLocker = &sync.RWMutex{}
	serverId    = g.Cfg().GetInt64(`server.id`, 1)
	defaultNode = NewNode()
)

func NewNode(names ...string) *Node {
	nodesLocker.Lock()
	defer nodesLocker.Unlock()

	name := NameDefault
	if len(names) > 0 {
		name = names[0]
	}

	if _, ok := nodes[name]; !ok {
		// 已经提前检查serverId，此处不再处理错误
		node, _ := snowflake.NewNode(serverId)
		nodes[name] = &Node{node}
	}

	return nodes[name]
}

// Id 大数字在浏览器丢失精度，全部使用字符串
func (n *Node) Id() string {
	return gconv.String(n.node.Generate().Int64())
}

// Id 默认的id生成器
func Id() string {
	return defaultNode.Id()
}

func init() {
	if serverId < 0 || serverId > 1<<10 {
		g.Log().Fatal(`server id 设置错误`)
	}
}
